<?php


namespace XinYaTable\Forms\Repositories;


use XinYaTable\Forms\Exceptions\FormException;
use XinYaTable\Forms\Models\EloquentFormFilterGroup;
use XinYaTable\Forms\Models\EloquentFormFilterGroupField;

class FormFilterGroupRepository extends BaseRepository
{
    private $_eloquentFormFilterGroup;

    private $_eloquentFormFilterGroupField;

    /**
     * FormFilterGroupRepository constructor.
     *
     * @param EloquentFormFilterGroup      $eloquentFormFilterGroup
     * @param EloquentFormFilterGroupField $eloquentFormFilterGroupField
     */
    public function __construct(EloquentFormFilterGroup $eloquentFormFilterGroup, EloquentFormFilterGroupField $eloquentFormFilterGroupField)
    {
        parent::__construct();
        $this->_eloquentFormFilterGroup      = $eloquentFormFilterGroup;
        $this->_eloquentFormFilterGroupField = $eloquentFormFilterGroupField;
    }

    /**
     * @param int $formId
     * @param int $uid
     *
     * @return mixed
     */
    public function getUserFilterGroup(int $formId, int $uid)
    {
        return $this->_eloquentFormFilterGroup
            ->newQuery()
            ->defaultFields()
            ->userFilterGroup($formId, $uid)
            ->with('conditions')
            ->orderBy('order')
            ->get();
    }

    /**
     * @param int $formId
     *
     * @return mixed
     */
    public function getSystemFilterGroup(int $formId)
    {
        return $this->_eloquentFormFilterGroup
            ->newQuery()
            ->defaultFields()
            ->systemFilterGroup($formId)
            ->with('conditions')
            ->orderBy('order')
            ->get();
    }

    /**
     * @param int $formId
     * @param int $uid
     *
     * @return \Illuminate\Support\Collection
     * @throws FormException
     */
    public function syncSystemToUser(int $formId, int $uid)
    {
        $_systemFilterGroup = $this->getSystemFilterGroup($formId);
        $_collection        = collect();
        if ($_systemFilterGroup->isNotEmpty()) {
            $_connection = $this->_eloquentFormFilterGroup->getConnection();
            $_connection->beginTransaction();
            try {
                foreach ($_systemFilterGroup as $filterGroup) {
                    $_userFilterGroup = $this->_eloquentFormFilterGroup->newInstance([
                        'form_id'   => $formId,
                        'title'     => $filterGroup->title,
                        'can_edit'  => $filterGroup->can_edit,
                        'is_system' => $filterGroup->is_system,
                        'uid'       => $uid,
                        'order'     => $filterGroup->order
                    ]);
                    $_userFilterGroup->save();
                    $_userFilterGroup->conditions = $_userFilterGroup->conditions()->createMany($filterGroup->conditions->toArray());
                    $_collection->push($_userFilterGroup);
                }
            } catch (\Exception $e) {
                $_connection->rollBack();
                throw new FormException(1020002);
            }
            $_connection->commit();
        }

        return $_collection;
    }

    /**
     * @param array $groupInfo
     * @param int   $formId
     * @param int   $uid
     *
     * @return EloquentFormFilterGroup
     */
    public function createUserFilterGroup(array $groupInfo, int $formId, int $uid)
    {
        $_newInstance            = $this->_eloquentFormFilterGroup->newInstance($groupInfo);
        $_newInstance->is_system = 0;
        $_newInstance->can_edit  = 1;
        $_newInstance->form_id   = $formId;
        $_newInstance->uid       = $uid;
        $_newInstance->save();
        $_newInstance->conditions = $_newInstance->conditions()->createMany(collect($groupInfo['conditions'])->map(function ($value) {
            $value['value'] = $value['value'] ?? '';

            return $value;
        })->toArray());

        return $_newInstance;
    }

    /**
     * @param int $filterGroupId
     * @param int $uid
     *
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|null|object
     * @throws FormException
     */
    public function deleteFilterGroup(int $filterGroupId, int $uid)
    {
        $filterInfo = $this->getFilterGroupByIdOrFail($filterGroupId, $uid);
        $this->_eloquentFormFilterGroup->newQuery()
            ->where('id', $filterGroupId)
            ->where('uid', $uid)
            ->update(['is_delete' => 1]);

        return $filterInfo;
    }

    /**
     * @param int   $id
     * @param int   $uid
     * @param array $fields
     *
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|null|object
     */
    public function getFilterGroupById(int $id, int $uid, array $fields = ['*'])
    {
        return $this->_eloquentFormFilterGroup
            ->newQuery()
            ->select($fields)
            ->where('id', $id)
            ->where('uid', $uid)
            ->with('conditions')
            ->first();
    }

    /**
     * @param int   $id
     * @param int   $uid
     * @param array $fields
     *
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|null|object
     * @throws FormException
     */
    public function getFilterGroupByIdOrFail(int $id, int $uid, array $fields = ['*'])
    {
        $_filterGroup = $this->getFilterGroupById($id, $uid, $fields);
        if (is_null($_filterGroup)) {
            throw new FormException(1020003);
        }

        return $_filterGroup;
    }

    /**
     * @param array $filterGroup
     * @param int   $id
     * @param int   $uid
     * @param null  $groupInfo
     *
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|null|object
     * @throws FormException
     */
    public function updateFilterGroup(array $filterGroup, int $id, int $uid, $groupInfo = null)
    {
        if (is_null($groupInfo)) {
            $groupInfo = $this->getFilterGroupByIdOrFail($id, $uid);
        }
        $groupInfo->fill($filterGroup);
        $groupInfo->save();
        if (isset($filterGroup['conditions'])) {
            $groupInfo->conditions()->delete();
            $groupInfo->conditions = $groupInfo->conditions()->createMany(collect($filterGroup['conditions'])->map(function ($value) {
                $value['value'] = $value['value'] ?? '';

                return $value;
            })->toArray());
        }

        return $groupInfo->attributesToArray();
    }

    /**
     * @param string $title
     * @param int    $uid
     * @param int    $id
     *
     * @return bool
     * @throws FormException
     */
    public function checkFilterGroupRepeat(string $title, int $uid, int $id = 0)
    {
        $_query = $this->_eloquentFormFilterGroup
            ->newQuery()
            ->where('title', $title)
            ->where('uid', $uid);
        $id > 0 && $_query->where('id', '!=', $id);
        if ($_query->exists()) {
            throw new FormException(1020004);
        }

        return false;
    }


}